﻿using soma.Helpers;
using soma.Models;
using soma.Models.Resources;
using soma.Services;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;

namespace soma.Controllers
{
    public class TwitterController : ApiController
    {
        private TwitterSearch twitterSearch;
        private object locker = new object();

        public TwitterController()
        {
            twitterSearch = new TwitterSearch();
        }

        [HttpPost]
        public HttpResponseMessage Post(Query query)
        {
            // lock (locker)
            {
                HttpResponseMessage responseMessage = new HttpResponseMessage();

                // TODO: Verify if the key is valid
                string errorMessage;
                if (!APIKeyVerifier.Instance.VerifyAPIKeyValidity(query.Key, out errorMessage))
                {
                    responseMessage.StatusCode = HttpStatusCode.Forbidden;
                    responseMessage.ReasonPhrase = errorMessage;
                    return responseMessage;
                }

                if (query.Results <= 0)
                {
                    responseMessage.StatusCode = HttpStatusCode.BadRequest;
                    responseMessage.ReasonPhrase = "The number of results must be greater than 0";
                    return responseMessage;
                }

                List<Tag> tagList = TagsSplitter.SplitAndDistributeTags(query.Tags, query.Results);

                if (query.UseSynonyms)
                {
                    // Get synonyms 
                    foreach (Tag tag in tagList)
                    {
                        int noSynonyms = (int)Math.Sqrt(tag.NumberResults);

                        if (noSynonyms == 0)
                        {
                            noSynonyms = 1;
                        }

                        List<string> synonymsForTag = SynonymsProvider.Instance.ProvideSynonyms(tag.TagName, noSynonyms);
                        foreach (string synonym in synonymsForTag)
                        {
                            tag.Synonyms.Add(new Tag(synonym, 0));
                        }
                    }

                    // Devide results between tags
                    foreach (Tag tag in tagList)
                    {
                        TagsSplitter.DivideResultBetweenTagAndSynonyms(tag);
                    }
                }

                List<Tag> allWordsList = new List<Tag>();
                foreach (Tag tag in tagList)
                {
                    allWordsList.Add(tag);
                    allWordsList.AddRange(tag.Synonyms);
                }

                List<Tag> tagsToSearch = new List<Tag>();
                foreach (Tag tag in allWordsList)
                {
                    // Verify if the time from when the last photo was uploaded and current time is bigger
                    // than constant. If so, download new photos, if not, get from cache. If this is 
                    // DateTime.MinValue no photo is present for that tag

                    DateTime latestMessageDateTime = MessagesRepository.Instance.GetDateTimeLatestResourceByTag(tag.TagName);
                    List<MessageResource> messageResourceList = null;

                    if (latestMessageDateTime.Equals(DateTime.MinValue) || latestMessageDateTime < DateTime.Now.AddMinutes((-1) * Constants.MIN_DIFF_TIME_RESOURCES))
                    {
                        tagsToSearch.Add(tag);
                    }
                    else
                    {
                        // Get the photos from repository
                        messageResourceList = MessagesRepository.Instance.GetResourceByTag(tag.TagName, tag.NumberResults).Cast<MessageResource>().ToList();
                    }
                }

                if (tagsToSearch.Count() > 0)
                {
                    twitterSearch.SearchMessagesByTag(tagsToSearch);
                }

                responseMessage.StatusCode = HttpStatusCode.OK;
                return responseMessage;
            }
        }
    }
}
